-- Author: shunguo.chen
-- Date: 2016-06-17 11:42:45
--
-- IMSimpleController
--

local IMSimpleView = import("..views.IMSimpleView")

local fileName = string.getModeName(...)
local ClassRef = class(fileName, app.mvc.ControllerBase)

local MAX_ITEM_CNT = 4

function ClassRef:ctor(params)
	self.super.ctor(self, params)

end

function ClassRef:init()
	self._model = app:getInst("IMModel")

	self._panelIdx = nil

	self._curChannelIdx = 1
	self._curP2PTarget = nil

	-- 缓存一段时间内的消息，只做一次显示
	self._newMsgs = nil
	self._newMsgsShowCronId = nil
end

function ClassRef:listEvent()
    return {
	    "im_newMessages",
		"onReconnectSuccessed",
		"updateMicAndSpeakBtnState",
	}
end

function ClassRef:onEvent(eventName, data)
	if eventName == "im_newMessages" then
		self:appendNewMsgs(data)
	elseif eventName == "onReconnectSuccessed" then
		self:onReconnectSuccessed()
	elseif eventName == "updateMicAndSpeakBtnState" then
		self:updateMicAndSpeakBtnState(data)
	end
end

-- showType =  Enums.IMSimpleShowType
-- posY =  y位置
-- isBattle =  是否战斗模式
-- zOrder = 层级 默认是 SceneZOrder.chatUiZOrder
function ClassRef:showView(showType, posY, isBattle, zOrder, battleType)
	showType = showType or Enums.IMSimpleShowType.all
	posY = posY or 0
	isBattle = isBattle or false
	zOrder = zOrder or SceneZOrder.chatUiZOrder
	if cc.isDead(self._view) then
		self._view = IMSimpleView.new(app.mvc.VIEWTYPE_NORMAL)
		self._view:onOperate(handler(self, self.onOperate))
		self:addChild(self._view)

		local hasMic, hasSpeaker = app:sendMsg("IMRecordController", "getMicSpeaker")
		self:updateWorld(self._model:isWorldOpen())
		self:updateTeam(self._model:isInTeam(), hasMic, hasSpeaker)
		self:updateGuild(self._model:isInGuild())
	end

    -- 新手战不显示
    if not app:isBattleGuideComp() then
        self._view:hide()
    else
        self._view:show(showType, posY, isBattle, battleType)
        self._view:setLocalZOrder(zOrder)
    end
end

function ClassRef:hideView(data)
	if not self:isViewAlive() then return end
	self._view:hide()
	self:clearNewMsgs()
end

function ClassRef:updateRanks(ranks)
	self._rankDataCache = ranks
	if not self:isViewAlive() then return end
	if self._panelIdx ~= 2 then return end

	self._view:refreshRanks(ranks)
end

function ClassRef:updateWorld(open)
	if self._view == nil then return end
	self._view:updateWorld(open)
end

function ClassRef:updateTeam(hasTeam)
	if self._view == nil then return end
	local hasMic, hasSpeaker = app:sendMsg("IMRecordController", "getMicSpeaker")
	self._view:updateTeam(hasTeam, hasMic, hasSpeaker)
end

function ClassRef:updateGuild(hasGuild)
	if self._view == nil then return end
	self._view:updateGuild(hasGuild)
end

function ClassRef:updateMessage(msg)
	if not self:isViewAlive() then return end
	self._view:updateMsg(msg)
end

function ClassRef:onReconnectSuccessed()
	if not self:isViewAlive() then return end
	-- 重连清理聊天记录
	self._view:clearMsgs()
	self:clearNewMsgs()
end

function ClassRef:updateMicAndSpeakBtnState(data)
	if not data then return end
	if cc.isDead(self._view) then return end
	self._view:updateMicAndSpeakBtnState(data.type, data.open)
end
----------------------------------------------------------------
function ClassRef:onOperate(operate, data)
	-- print("IMSimpleController:onOperate", operate, data)
	if operate == "showRoom" then
		-- self._view:hide()
		app:sendMsg("IMRoomController", "showView")
	elseif operate == "mic" then
		app:sendMsg("IMRecordController", "openMic", data)
	elseif operate == "speaker" then
		app:sendMsg("IMRecordController", "openSpeaker", data)
	elseif operate == "quickMsg" then
		app:sendMsg("IMModel", "sendTeamMessage", data)
	elseif operate == "switchPanel" then
		-- data = 1 聊天信息
		-- data = 2	排行信息
		if self._panelIdx ~= data then
			self._panelIdx = data
			if data == 1 then
				local msgs 
				if self._curChannelIdx == 6 then
					local uid = self._curP2PTarget and self._curP2PTarget.uid or nil
					msgs = self._model:getChannelData(self._curChannelIdx, nil, uid)
				else
					msgs= self._model:getChannelData(self._curChannelIdx, true)
				end
				local newMsgs = self:getShowMsgs(msgs)
				self._view:refreshMsgs(newMsgs, self._curChannelIdx)
			else
				self._view:refreshRanks(self._rankDataCache or {})
				self:clearNewMsgs()
			end
		end
	end
end

-- 清理新消息缓存
function ClassRef:clearNewMsgs()
	self._newMsgs = nil
	if self._newMsgsShowCronId then
		scheduler.cancelCron(self._newMsgsShowCronId)
		self._newMsgsShowCronId = nil
	end
end

function ClassRef:appendNewMsgs(msgs)
	if not self:isViewAlive() then return end
	if not self._view:isMsgListVisible() then return end
	if self._panelIdx ~= 1 then return end

	if #msgs == 0 then return end
	local newMsgs = {}
	for i,msg in ipairs(msgs) do
		if self:isMsgInCurChannel(msg) and self:isShowMessage(msg) then
			newMsgs[#newMsgs + 1] = msg
		end
	end

	if not self._newMsgs then
		self._newMsgs = newMsgs
	else
		self._newMsgs = table.attach(self._newMsgs, newMsgs)
	end

	-- 收集消息，0.2秒show一次
	if self._newMsgsShowCronId then return end
	self._newMsgsShowCronId = scheduler.newCron(function()
		local len = #self._newMsgs
		local showMsgs = self._newMsgs
		self._newMsgs = nil
		self._newMsgsShowCronId = nil

		if len >= MAX_ITEM_CNT then
			local start = math.max(len-MAX_ITEM_CNT+1, 1)
			self._view:refreshMsgs(table.sub(showMsgs, start))
		else
			for i,msg in ipairs(showMsgs) do
				-- 1.忽略和前一个数据相同的
				local newData = self._view:getNewItemData()
				if newData ~= msg then
					self._view:addNewMsgItem(msg)
				end
			end
		end
	end, 0.2)
end

function ClassRef:switchChannel()
	-- 切换显示频道
	self._curChannelIdx = self._model:getCurChannelIdx()
	self._curP2PTarget = self._model:getCurP2PTarget()
	if self._panelIdx == 1 then
		local msgs
		if self._curChannelIdx == 6 then
			local uid = self._curP2PTarget and self._curP2PTarget.uid or nil
			msgs = self._model:getChannelData(self._curChannelIdx, nil, uid)
		else
			msgs = self._model:getChannelData(self._curChannelIdx, true)
		end
		local newMsgs = self:getShowMsgs(msgs)
		self._view:refreshMsgs(newMsgs, self._curChannelIdx)
	end

	self:clearNewMsgs()
end

function ClassRef:isMsgInCurChannel(msg)
	local isCurChannel
	local isP2p = msg.sessionType == im.SessionType.P2p
	if self._curChannelIdx == 1 then
		isCurChannel = msg.showFlag
	elseif self._curChannelIdx == 2 then
		isCurChannel = msg.channelId == "world"
	elseif self._curChannelIdx == 3 then
		isCurChannel = msg.channelId == "team"
	elseif self._curChannelIdx == 4 then
		isCurChannel = msg.channelId == "guild"
	elseif self._curChannelIdx == 5 then
		isCurChannel = msg.channelId == "map"
	elseif self._curChannelIdx == 6 then
		isCurChannel = isP2p and self:_recvP2pMsg(msg)
	elseif self._curChannelIdx == 7 then
		isCurChannel = msg.channelId == "teamreq"
	elseif self._curChannelIdx == 8 then
		isCurChannel = msg.channelId == "system"
	end
	return isCurChannel
end

function ClassRef:_recvP2pMsg(msg)
	local isCurChannel = false
	local target = msg:getP2pInfo()
	if self._curP2PTarget and target.uid == self._curP2PTarget.uid then
		isCurChannel = true
	end
	return isCurChannel
end

function ClassRef:isShowMessage(msg)
	local isShow = false
	if self._curChannelIdx ~= 1 or (self._curChannelIdx == 1 and msg.showFlag == true) then
		isShow = true
	end
	return isShow
end

function ClassRef:getShowMsgs(msgs)
	local newMsgs = {}
	if self._curChannelIdx ~= 1 then
		newMsgs = msgs
	else
		for i, msg in ipairs(msgs) do
			if self:isShowMessage(msg) then
				table.insert(newMsgs, msg)
			end
		end
	end
	return newMsgs
end

return ClassRef
